import datetime
import json
from flask import request, Blueprint, current_app, Response
import uuid
from common.utils import jenkins_util
from extensions.init_scheduler import scheduler
from common.utils import mysql_utils

scheduler_bp = Blueprint('scheduler', __name__, url_prefix='/scheduler')
app = current_app


@scheduler_bp.route('/job_create', methods=['POST'])
def job_create():
    jobargs = json.loads(request.get_data().decode())
    env = jobargs['env']
    git_address = jobargs['git_address']
    branch = jobargs['branch']
    build_title = jobargs['build_title']
    build_remark = jobargs['build_remark']
    build_app_name = jobargs['build_app_name']

    url = current_app.config["JENKINS_URL"]
    username = current_app.config["JENKINS_USERNAME"]
    password = current_app.config["JENKINS_PASSWORD"]
    with mysql_utils.DB_MySQL() as db:
        job_name = db.select_one(
            "select jenkins_appname from jenkins_apps where env = '{}' and appname = '{}'".format(env, build_app_name))[
            "jenkins_appname"]

    j = jenkins_util.Jenkins_util(url, username, password, job_name, git_address, branch)
    task_id = str(uuid.uuid1().int)
    result = {"code": 0, "task_id": task_id, "message": "构建成功，请关注后续应用状态。"}
    try:
        j.build_job()
    except:
        result["message"] = '构建失败，请联系管理员。'
        return result

    try:
        add_cron(task_id, 'interval', 60, j)
    except Exception as e:
        print(e)
        result["message"] = '创建监听任务失败，请手动检查任务构建状态。'

    build_data_sql = '''
    insert into application_apply values (NULL, '{}','{}','{}','{}','{}','{}','{}','{}','{}','{}',{},{})'''.format(
        build_app_name, build_title, env, '', build_remark, branch,
        datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"), datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
        '应用发布中', task_id, 0, git_address)
    with mysql_utils.DB_MySQL() as db:
        db.insert(build_data_sql)

    return result


@scheduler_bp.route('/job_list', methods=['GET'])
def job_list():
    result = {"code": 0, "job_list": '', "message": ""}

    try:
        with mysql_utils.DB_MySQL() as db:
            job_list = db.select_all('select * from application_apply aa where effective = 0')
    except:
        result["message"] = '查询任务列表异常。'
        result["code"] = 1

    job_list = [{
        "apply_date": i["apply_date"].strftime("%Y-%m-%d %H:%M:%S"),
        "apply_title": i["apply_title"],
        "apply_appname": i["app_name"],
        "apply_env": i["env"],
        "apply_version": i["version"],
        "apply_remark": i["remarks"],
        "apply_status": i["apply_status"]
    } for i in job_list]

    result = {"code": 0, "job_list": job_list, "message": ""}

    return result


@scheduler_bp.route('/env_list', methods=['GET'])
def env_list():
    result = {"code": 0, "env_list": '', "message": ""}

    try:
        with mysql_utils.DB_MySQL() as db:
            env_list = db.select_all('select distinct env  from jenkins_apps')
    except:
        result["message"] = '查询环境列表异常。'
        result["code"] = 1

    env_list = [i["env"] for i in env_list]

    result = {"code": 0, "env_list": env_list, "message": ""}

    return result


@scheduler_bp.route('/app_list', methods=['GET'])
def app_list():
    env = request.args.get("env")

    result = {"code": 0, "app_list": '', "message": ""}

    try:
        with mysql_utils.DB_MySQL() as db:
            app_list = db.select_all('select appname  from jenkins_apps where env = "{}"'.format(env))
    except:
        result["message"] = '查询应用列表异常。'
        result["code"] = 1

    app_list = [i["appname"] for i in app_list]

    result = {"code": 0, "app_list": app_list, "message": ""}

    return result


@scheduler_bp.route('/app_default_info', methods=['GET'])
def app_default_info():
    env = request.args.get("env")
    appname = request.args.get("appname")

    result = {"code": 0, "env_list": '', "message": ""}

    try:
        with mysql_utils.DB_MySQL() as db:
            default_info = db.select_all('''
            select default_git_addr, default_git_branch  from jenkins_apps where env = '{}' and appname = '{}'
                                     '''.format(env, appname))
    except:
        result["message"] = '查询应用默认信息异常。'
        result["code"] = 1

    result = {"code": 0, "default_git_addr": default_info[0]["default_git_addr"],
              "default_git_branch": default_info[0]["default_git_branch"], "message": ""}

    return result


@scheduler_bp.route('/appinfo', methods=['GET'])
def get_app_info():
    env = request.args.get("env")
    build_app_name = request.args.get("build_app_name")
    result = {"code": 0, "git_addr": '', 'git_branch_default': '',
              "git_branch_list": ['dev_std', 'beta_std', 'rc_std', 'release'],
              "message": ""}

    try:
        with mysql_utils.DB_MySQL() as db:
            tmp = db.select_one(
                "select jenkins_appname ,default_git_addr, default_git_branch where env = '{}' and appname = '{}'".format(
                    env,
                    build_app_name))
            result['git_addr'] = tmp["default_git_addr"]
            result['git_branch_default'] = tmp["default_git_branch"]
    except:
        result["message"] = '获取应用默认信息失败。'
        result["code"] = 1

    return Response(json.dumps(result, default=str, bigint_as_string=True, encoding="latin1"),
                    content_type="application/json")


def job_scheduler(*args):
    result = args[1].job_status()
    task_id = args[0]
    if result:
        print('未构建完成。', datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    else:

        # 这个分支代表着job构建完了，1. 需要删除定时任务。2. 需要发通知，构建完成，并将构建的内容输出
        res = remove_job(task_id)
        if res:
            with mysql_utils.DB_MySQL() as db:
                db.update(
                    "update application_apply set build_status = '发布成功'   where task_id = '{}'".format(task_id))
            print(args[1].job_last_build_info())
        else:
            with mysql_utils.DB_MySQL() as db:
                db.update(
                    "update application_apply set build_status = '发布失败' where task_id = '{}' ".format(task_id))


# 新增job
def add_cron(task_id, trigger_type, interval_time, job: jenkins_util):
    seconds = int(interval_time)
    if seconds <= 0:
        raise TypeError('请输入大于0的时间间隔！')
    scheduler.add_job(func=job_scheduler,
                      trigger=trigger_type,
                      seconds=seconds,
                      replace_existing=True,
                      coalesce=True,
                      id=task_id,
                      args=[task_id, job])
    return True


def remove_job(task_id):
    flag = False
    try:
        scheduler.remove_job(task_id)
        flag = True
    except Exception as e:
        print(e)
    return flag


def reg_schedule_bp(app):
    app.register_blueprint(scheduler_bp)
